package com.ibm.cps.message.validation;

import java.util.Collection;

import com.fasterxml.jackson.databind.node.ObjectNode;
import com.ibm.cps.message.MessageFields;
import com.ibm.util.ErrorCode;
import com.ibm.util.JSONUtility;
import com.ibm.util.exception.CPSException;

public class ValidatorUtil {
	public static void validateStringFields(ObjectNode element, String... strFields) throws CPSException {
		if (strFields == null) {
			return;
		}
		for (int i = 0; i < strFields.length; i++) {
			if (!JSONUtility.isStringField(element, strFields[i])) {
				throw new CPSException(ErrorCode.ERROR_FIELD_TYPE,
						"Field [" + strFields[i] + "] should be string in " + element.toString());
			}
		}
	}

	static public void validateIntFields(ObjectNode element, String... strFields) throws CPSException {
		if (strFields == null) {
			return;
		}
		for (int i = 0; i < strFields.length; i++) {
			if (!JSONUtility.isIntField(element, strFields[i])) {
				throw new CPSException(ErrorCode.ERROR_FIELD_TYPE,
						"Field " + strFields[i] + " should be a integer in " + element.toString());
			}
		}
	}

	static public void validateBooleanFields(ObjectNode element, String... strFields) throws CPSException {
		if (strFields == null) {
			return;
		}
		for (int i = 0; i < strFields.length; i++) {
			if (!JSONUtility.isBooleanField(element, strFields[i])) {
				throw new CPSException(ErrorCode.ERROR_FIELD_TYPE,
						"Field " + strFields[i] + " should be a boolean in " + element.toString());
			}
		}
	}

	static public void validateObjectFields(ObjectNode element, String... strFields) throws CPSException {
		if (strFields == null) {
			return;
		}
		for (int i = 0; i < strFields.length; i++) {
			if (!JSONUtility.isJsonObjectField(element, strFields[i])) {
				throw new CPSException(ErrorCode.ERROR_FIELD_TYPE,
						"Field " + strFields[i] + " should be a json object in " + element.toString());
			}
		}
	}

	static public void validateArrayFields(ObjectNode element, String... strFields) throws CPSException {
		if (strFields == null) {
			return;
		}
		for (int i = 0; i < strFields.length; i++) {
			if (!JSONUtility.isArrayField(element, strFields[i])) {
				throw new CPSException(ErrorCode.ERROR_FIELD_TYPE,
						"Fileld " + strFields[i] + " should be an array in " + element.toString());
			}
		}
	}

	static public void assignRandomIdIfNotPresent(ObjectNode element, String fieldName) {
		if (!element.has(fieldName) || !JSONUtility.isStringField(element, fieldName)) {
			JSONUtility.assignRandomValue(element, fieldName);
		}
	}

	public static void validateAllTypeFields(ObjectNode object, String[] strFields, String[] arrayFields,
			String[] booleanFields, String[] intFields) throws CPSException {
		validateStringFields(object, strFields);
		validateIntFields(object, intFields);
		validateArrayFields(object, arrayFields);
		validateBooleanFields(object, booleanFields);
	}

	public static void validateAllTypeFields(ObjectNode object, Collection<String> strFields,
			Collection<String> arrayFields, Collection<String> booleanFields, Collection<String> intFields,
			Collection<String> objectFields) throws CPSException {
		validateStringFields(object, strFields.toArray(new String[strFields.size()]));
		validateIntFields(object, intFields.toArray(new String[intFields.size()]));
		validateArrayFields(object, arrayFields.toArray(new String[arrayFields.size()]));
		validateBooleanFields(object, booleanFields.toArray(new String[booleanFields.size()]));
		validateObjectFields(object, objectFields.toArray(new String[booleanFields.size()]));
	}

	public static void commonProcess(ObjectNode element) throws CPSException {
		if (element.has(MessageFields.PARENTPROCESSORS)) {
			JSONUtility.convertField2Array(element, MessageFields.PARENTPROCESSORS);
		}
		ValidatorUtil.assignRandomIdIfNotPresent(element, MessageFields.PROCESSORID);
	}

	public static boolean checkNotNull(String key, Object value) throws CPSException {
		if (value == null) {
			throw new CPSException(ErrorCode.ERROR_FIELD_TYPE, "The value of field " + key + " is null.");
		}
		return true;
	}

	public static void addDefaultType(ObjectNode node, String type) {
		if (node.get(type) == null) {
			node.put(type, MessageFields.MESSAGEQUEUE);
		}
	}
}
